/**
 * Testing functions
 */
#ifdef DEBUG

#include "bindings/bindings_font_test.h"

#include "helpers/font_helper.h"
#include "helpers/general.h"
#include "helpers/resource.h"
#include "rive/text/utf.hpp"

namespace ohos_rive {

napi_value FontTestCleanupFallbacks(napi_env env, napi_callback_info info)
{
    FontHelper::s_fallbackFonts.clear();
    FontHelper::resetCache();

    napi_value undefined;
    napi_get_undefined(env, &undefined);

    return undefined;
}

napi_value FontTestGetSystemFontBytes(napi_env env, napi_callback_info info)
{
    std::vector<uint8_t> bytes = FontHelper::GetSystemFontBytes();
    auto len = bytes.size();
    if (len == 0) {
        LOGE("cppGetSystemFontBytes - GetSystemFontBytes() returned no data");
        napi_value emptyArray;
        napi_create_array(env, &emptyArray);
        return emptyArray;
    }

    napi_value array;
    void *buffer;
    auto status = napi_create_arraybuffer(env, len, &buffer, &array);
    if (status != napi_ok) {
        LOGE("create napi array failed.");
        return nullptr;
    }

    memcpy(buffer, bytes.data(), len);

    return array;
}

napi_value FontTestFindFontFallback(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    auto status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    if (status != napi_ok || argc < 2) {
        LOGE("Invalid arguments, actual number of arguments is %ld", argc);
        return nullptr;
    }

    uint32_t missingCodePoint;
    status = napi_get_value_uint32(env, args[0], &missingCodePoint);
    if (status != napi_ok) {
        LOGE("Get missingCodePoint failed.");
        return nullptr;
    }
    auto bytes = ByteArrayToUint8Vec(env, args[1]);
    rive::rcp<rive::Font> aFont = HBFont::Decode(bytes);

    // Try to find a font with the missing code point
    int fallbackIndex = 0;
    rive::rcp<rive::Font> fontWithGlyph = FontHelper::FindFontFallback(missingCodePoint, fallbackIndex, aFont.get());

    // Search through fallbacks until we find one with the glyph or run out
    // of options
    while (fontWithGlyph != nullptr && !fontWithGlyph->hasGlyph(missingCodePoint)) {
        fallbackIndex++;
        fontWithGlyph = FontHelper::FindFontFallback(missingCodePoint, fallbackIndex, aFont.get());
    }

    LOGI("Font fallback search result: %s", fontWithGlyph != nullptr ? "FOUND" : "NOT FOUND");

    aFont->ref(); // Kept alive for testing.
    // Use this convention for testing:
    // return -1 if we didn't find a fallback
    // return fallbackIndex to signal which index found the match
    napi_value fallbackIndexValue;
    status = napi_create_int32(env, fallbackIndex, &fallbackIndexValue);
    if (status != napi_ok) {
        LOGE("Create fallback Index napi value failed.");
        return nullptr;
    }
    return fallbackIndexValue;
}

} // namespace ohos_rive

#endif // DEBUG
